package com.yunsc.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunsc.common.utils.PageResult;
import com.yunsc.media.entity.YunscUploadFileEntity;
import com.yunsc.media.service.YunscUploadFileService;
import com.yunsc.product.dao.YunscCommentDao;
import com.yunsc.product.dto.CommentDTO;
import com.yunsc.product.dto.QueryCommentDTO;
import com.yunsc.product.entity.YunscCommentEntity;
import com.yunsc.product.entity.YunscCommentImageEntity;
import com.yunsc.product.service.YunscCommentImageService;
import com.yunsc.product.service.YunscCommentService;
import com.yunsc.product.service.YunscGoodsService;
import com.yunsc.product.vo.CommentOrderGoods;
import com.yunsc.product.vo.CommentTotalVO;
import com.yunsc.product.vo.GoodsCommentVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("yunscCommentService")
public class YunscCommentServiceImpl extends ServiceImpl<YunscCommentDao, YunscCommentEntity> implements YunscCommentService {

    @Resource
    private YunscGoodsService goodsService;
    @Resource
    private YunscUploadFileService uploadFileService;
    @Resource
    private YunscCommentImageService commentImageService;

    @Override
    public PageResult<GoodsCommentVO> queryCommentList(QueryCommentDTO commentDTO, Integer storeId) {
        Page<GoodsCommentVO> pageResult = this.baseMapper.queryCommentPage(
                new Page<>(commentDTO.getPage(), commentDTO.getLimit()),
                commentDTO,
                storeId
        );
        pageResult.getRecords().forEach(comment -> {
            CommentOrderGoods orderGoods = comment.getOrderGoods();
            orderGoods.setGoodsProps(JSON.parseObject(orderGoods.getGoodsProps().toString(), List.class));
            YunscUploadFileEntity goodsImage = uploadFileService.getById(orderGoods.getGoodsImage()); // 商品图片
            orderGoods.setGoodsImage(goodsImage == null? "" : goodsImage.getExternalUrl());
            comment.setImages(getCommentImages(comment.getCommentId()));
            YunscUploadFileEntity userImage = uploadFileService.queryFileById(comment.getUser().getAvatarId());
            comment.getUser().setAvatarUrl(userImage == null? "" : userImage.getExternalUrl());
        });
        return PageResult.formatPageResult(pageResult.getRecords(), commentDTO.getPage(), commentDTO.getPageSize(), pageResult.getTotal());
    }

    private List<YunscCommentImageEntity> getCommentImages(Integer commentId) {
        LambdaQueryWrapper<YunscCommentImageEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(YunscCommentImageEntity::getCommentId, commentId);
        List<YunscCommentImageEntity> commentImageEntities = commentImageService.list(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(commentImageEntities)){
            return Collections.emptyList();
        }
        commentImageEntities.forEach(commentImage -> {
            commentImage.setImageUrl(uploadFileService.queryFileUrlById(commentImage.getImageId()));
        });
        return commentImageEntities;
    }

    @Override
    public GoodsCommentVO queryCommentDetail(Integer commentId) {
        YunscCommentEntity commentEntity = this.getOne(new QueryWrapper<YunscCommentEntity>()
                .eq("comment_id", commentId));
        if (commentEntity == null){
            return null;
        }
        GoodsCommentVO commentVO = new GoodsCommentVO();
        BeanUtils.copyProperties(commentEntity, commentVO);
        LambdaQueryWrapper<YunscCommentImageEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(YunscCommentImageEntity::getCommentId, commentId);
        List<YunscCommentImageEntity> commentImageEntities = commentImageService.list(lambdaQueryWrapper);
        List<Integer> imageIds = commentImageEntities.stream().map(YunscCommentImageEntity::getImageId).collect(Collectors.toList());
        commentVO.setImageIds(imageIds);
        List<YunscUploadFileEntity> files = uploadFileService.queryFilesByIds(imageIds);
        commentVO.setImageList(files);
        commentVO.setImages(commentImageEntities);
        return commentVO;
    }

    @Override
    @Transactional
    public void editComment(CommentDTO params) {
        Integer commentId = params.getCommentId();
        YunscCommentEntity comment = this.getById(commentId);
        CommentDTO.CommentForm commentForm = params.getForm();
        comment.setScore(commentForm.getScore());
        comment.setContent(commentForm.getContent());
        comment.setStatus(commentForm.getStatus());
        comment.setSort(commentForm.getSort());
        this.updateById(comment);
        if (CollectionUtils.isEmpty(commentForm.getImageIds())){
            return;
        }
        List<Integer> imageIds = commentForm.getImageIds();
        LambdaQueryWrapper<YunscCommentImageEntity> eq = new LambdaQueryWrapper<YunscCommentImageEntity>().eq(YunscCommentImageEntity::getCommentId, commentId);
        List<YunscCommentImageEntity> commentImageEntities = commentImageService.list(eq);
        List<Integer> oldImageIds = commentImageEntities.stream().map(YunscCommentImageEntity::getImageId).collect(Collectors.toList());
        commentImageService.removeByIds(oldImageIds);
        imageIds.forEach(imageId -> {
            YunscCommentImageEntity commentImage = new YunscCommentImageEntity();
            commentImage.setCommentId(commentId);
            commentImage.setImageId(imageId);
            commentImage.setStoreId(comment.getStoreId());
            commentImageService.save(commentImage);
        });
    }

    @Override
    @Transactional
    public void deleteComment(Integer commentId) {
        this.update(new UpdateWrapper<YunscCommentEntity>().eq("comment_id", commentId)
                .set("is_delete", 1));
    }

    @Override
    public CommentTotalVO queryCommentTotal(Integer goodsId) {
        LambdaQueryWrapper<YunscCommentEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YunscCommentEntity::getGoodsId, goodsId);
        queryWrapper.eq(YunscCommentEntity::getIsDelete, 0);
        List<YunscCommentEntity> list = this.list(queryWrapper);

        Map<Integer, Long> scoreCounts = list.stream()
                .collect(Collectors.groupingBy(YunscCommentEntity::getScore, Collectors.counting()));

        long allCount = list.size();
        long praiseCount = scoreCounts.getOrDefault(10, 0L);
        long reviewCount = scoreCounts.getOrDefault(20, 0L);
        long negativeCount = scoreCounts.getOrDefault(30, 0L);
        CommentTotalVO commentTotalVO = new CommentTotalVO();
        commentTotalVO.setAll((int) allCount);
        commentTotalVO.setPraise((int) praiseCount);
        commentTotalVO.setReview((int) reviewCount);
        commentTotalVO.setNegative((int) negativeCount);
        return commentTotalVO;
    }


}